#include <osa.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h> 
#include <string.h>

#include "rtc.h"


OST_MSG_CB  os_msg_rtc_update_cb;
OST_MSG_CB	os_msg_rtc_setup_cb;


// RTC variables
static volatile struct
{
	unsigned int mili_sec;
	unsigned char second;
	unsigned char minute;
	unsigned char hour;
	unsigned char req_update;
}
sys_rtc_time;


#define RTC_TIME_INTERVAL 1000 ms

/********************************************************************************
 *                                                                              *
 *  TASK:           TIMER2_OVF_vect                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
//Overflow ISR
ISR(TIMER2_OVF_vect)
{
	sys_rtc_time.mili_sec += 1000; //100 milisec over flow
	
	if(sys_rtc_time.mili_sec >= 1000)
	{
		sys_rtc_time.mili_sec = 0;
		sys_rtc_time.second++;
		if(sys_rtc_time.second >= 60)
		{					
			sys_rtc_time.second -= 60;
			sys_rtc_time.minute++;
			if(sys_rtc_time.minute >= 60)
			{
				sys_rtc_time.minute = 0;
				sys_rtc_time.hour++;
				if(sys_rtc_time.hour >= 24)
				{
					sys_rtc_time.hour = 0;
				}		
			}
			sys_rtc_time.req_update = TRUE;
		}		
	}
}

/********************************************************************************
 *                                                                              *
 *  TASK:           InitRTC                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void InitRTC( void )
{
    //Disable timer2 interrupts
    TIMSK2  = 0;
    //Enable asynchronous mode
    ASSR  = _BV(AS2);
    //set initial counter value
    TCNT2=0;
    //set prescaller 128
    TCCR2B |= _BV(CS22)|_BV(CS00);
    //wait for registers update
    // while (!(ASSR & ((1<<TCN2UB)|(1<<TCR2BUB))));
    //clear interrupt flags
    TIFR2  = _BV(TOV2);
    //enable TOV2 interrupt
    TIMSK2  = _BV(TOIE2);
	
	OS_Msg_Create(os_msg_rtc_update_cb);
	OS_Msg_Create(os_msg_rtc_setup_cb);
	
	memset((void *)((char *)&sys_rtc_time),0,sizeof(sys_rtc_time));
	sys_rtc_time.req_update = TRUE;
}

/********************************************************************************
 *                                                                              *
 *  TASK:           TimeUpdate                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void TimeUpdate (void)
{
	static unsigned char rtc_time[2];

	rtc_time[0] = sys_rtc_time.hour;
	rtc_time[1] = sys_rtc_time.minute;

	OS_Msg_Send(os_msg_rtc_update_cb, (char *)rtc_time);
}


/********************************************************************************
 *                                                                              *
 *  TASK:           TimeSetup                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void TimeSetup (char hour,char minute)
{	
	if(hour < 24 && minute < 60)
	{
		//disable TOV2 interrupt
		TIMSK2  &= ~_BV(TOIE2);
		
		sys_rtc_time.mili_sec	= 0;
		sys_rtc_time.second		= 0;
		sys_rtc_time.minute		= minute;
		sys_rtc_time.hour		= hour;

		//enable TOV2 interrupt
		TIMSK2  |= _BV(TOIE2);
	}
}




/********************************************************************************
 *                                                                              *
 *  TASK:           TaskRTC                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void TaskRTC (void)
{
	OST_MSG rtc_msg;
	//printf("TaskRTC\r\n");
	
    for (;;)
    {	
		OS_Msg_Wait_TO(os_msg_rtc_setup_cb, rtc_msg, RTC_TIME_INTERVAL);
        if (!OS_IsTimeout()) {
			//@TH printf("Setup %d %02d:%02d\r\n",(int)((char *)rtc_msg)[0],(int)((char *)rtc_msg)[1],(int)((char *)rtc_msg)[2]);			
			if(((char *)rtc_msg)[0] == FALSE)
			{
				sys_rtc_time.req_update = TRUE;
			}
			else
			{				
				TimeSetup(((char *)rtc_msg)[1],((char *)rtc_msg)[2]);			
			}			
        }
		else
		{
			if(sys_rtc_time.req_update == TRUE)
			{
				TimeUpdate();
				sys_rtc_time.req_update = FALSE;
			}
						
		}
		
    }
}
